package me.zhengjie.controller.test;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import me.zhengjie.dao.*;
import me.zhengjie.mapper.MaterialMapper;
import me.zhengjie.mapper.StoreTotalMapper;
import me.zhengjie.server.*;
import me.zhengjie.utils.ExecutorUtil;
import me.zhengjie.utils.SnowIdUtil;
import me.zhengjie.vo.Result;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

import static me.zhengjie.controller.test.DataGenerator.*;

@RestController
@RequestMapping("api/createDate")
public class createData {

    @Resource
    private StoreLocalService storeLocalService;

    @Resource
    private StoreOutsideService storeOutsideService;

    @Resource
    private MaterialMapper materialMapper;

    @Resource
    private StoreTotalMapper storeTotalMapper;

    @Resource
    private ContainerService containerService;
    @Resource
    private MaterialService materialService;
    @Resource
    private DispositionService dispositionService;
    @Resource
    private MesSyncService mesSyncService;
    @Resource
    private MergeTaskService mergeTaskService;
    @Resource
    private FreezeService freezeService;
    @Resource
    private InventoryTaskService inventoryTaskService;

    @Resource
    private TransactionTemplate transactionTemplate;

    @GetMapping("79")
    public void test79() {
        LambdaQueryWrapper<StoreLocalDao> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(StoreLocalDao::getContainerCode, StoreLocalDao::getId);
        queryWrapper.groupBy(StoreLocalDao::getContainerCode).groupBy(StoreLocalDao::getId);
        List<StoreLocalDao> containerCodeList = storeLocalService.list(queryWrapper);

        HashMap<String, List<StoreLocalDao>> hashMap = new HashMap<>();
        for (StoreLocalDao storeOutsideDao : containerCodeList) {
            if (hashMap.containsKey(storeOutsideDao.getContainerCode())) {
                List<StoreLocalDao> storeLocalDaos = hashMap.get(storeOutsideDao.getContainerCode());
                storeLocalDaos.add(storeOutsideDao);
            } else {
                List<StoreLocalDao> storeLocalDaos = new ArrayList<>();
                storeLocalDaos.add(storeOutsideDao);
                hashMap.put(storeOutsideDao.getContainerCode(), storeLocalDaos);
            }
        }
        for (Map.Entry<String, List<StoreLocalDao>> entry : hashMap.entrySet()) {
            List<StoreLocalDao> value = entry.getValue();
            if (value.size() > 1) {
                StoreLocalDao storeLocalDao = value.get(0);
                storeLocalDao.setStatus(0);
                storeLocalDao.setContainerCode("1111");
                storeLocalService.updateById(storeLocalDao);
            }
        }


    }

    @GetMapping("69")
    public void test69() throws InterruptedException {
        LambdaQueryWrapper<MaterialDao> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(MaterialDao::getContainerCode);
        queryWrapper.groupBy(MaterialDao::getContainerCode);
        List<MaterialDao> containerCodeList = materialMapper.selectList(queryWrapper);

        LambdaQueryWrapper<StoreLocalDao> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.select(StoreLocalDao::getContainerCode, StoreLocalDao::getId);
        queryWrapper1.groupBy(StoreLocalDao::getContainerCode).groupBy(StoreLocalDao::getId);
        List<StoreLocalDao> StoreLocalList = storeLocalService.list(queryWrapper1);
        HashSet<String> hashSet = new HashSet<>();
        for (StoreLocalDao storeLocalDao : StoreLocalList) {
            hashSet.add(storeLocalDao.getContainerCode());
        }

        int k = 400;
        List<StoreLocalDao> localDaoList = storeLocalService.list();
        List<StoreOutsideDao> list = storeOutsideService.list();
        for (int i = 0; i < containerCodeList.size(); i++) {
            MaterialDao materialDao = containerCodeList.get(i);
            if (materialDao == null || materialDao.getContainerCode() == null) {
                continue;
            }
            if (k > 0) {
                StoreLocalDao storeLocalDao = localDaoList.get(i);
                if (storeLocalDao == null) {
                    continue;
                }
                if (hashSet.contains(materialDao.getContainerCode())) {
                    continue;
                }
                if (hashSet.contains(storeLocalDao.getContainerCode())) {
                    continue;
                }
                storeLocalDao.setContainerCode(materialDao.getContainerCode());
                storeLocalDao.setStatus(3);
                storeLocalService.updateById(storeLocalDao);
                k--;
            }


//            if (i >= 100) {
//                StoreOutsideDao storeOutsideDao = list.get(i - 100);
//                if (storeOutsideDao == null) {
//                    continue;
//                }
//                storeOutsideDao.setContainerCode(materialDao.getContainerCode());
//                storeOutsideDao.setStatus(3);
//                storeOutsideService.updateById(storeOutsideDao);
//            }
        }

    }

    @GetMapping("19")
    public void test91() throws InterruptedException {
//

//        for (int i = 1; i < 25; i++) {
//            int finalI = i;
//            executorServer.submit(() -> {
//                Page<MaterialDao> materialDaoList = materialMapper.selectPage(new Page<>(finalI, 100000), wrapper);
//                System.out.println("*********第" + finalI + "页**************: " + materialDaoList.getRecords().size());
//                for (MaterialDao materialDao : materialDaoList.getRecords()) {
//                    String containerCode = materialDao.getContainerCode();
//                    StoreLocalDao storeLocalDao = storeLocalService.findContainerCode(containerCode);
//
//                    if (storeLocalDao == null) {
//                        StoreOutsideDao byContainerCode = storeOutsideService.findStoreByContainerCode(containerCode);
//                        if (byContainerCode != null) {
//                            materialDao.setWarehouse(byContainerCode.getFloor());
//                            materialDao.setIssuePosition(byContainerCode.getId());
//                        }
//                    }else {
//                        materialDao.setWarehouse(storeLocalDao.getFloor());
//                        materialDao.setIssuePosition(storeLocalDao.getId());
//                    }
//                    materialService.updateByItemBarCode(materialDao);
//                }
//
//                System.out.println("*********第" + finalI + "页**************: ");
//            });
//        }
//        if (!executorServer.awaitTermination(5, TimeUnit.MINUTES)) {
//            // 如果超过了60分钟还没有全部完成则强制中断剩余未完成的任务.
//            System.out.println("线程任务超时》》》》》》》》》》》》");
//        }
    }

    @GetMapping("29")
    public Result<?> test92() {
        Result<?> existTask = mergeTaskService.findExistTask();
        Result<?> existTask1 = freezeService.findExistTask();
        Result<?> existTask2 = inventoryTaskService.findExistTask();

        return Result.success();
    }


    @GetMapping("09")
    public void test90() throws InterruptedException {
        test0();
        test01();
        test02();
        test03();
        test04();
        System.out.println("所有都执行完！！！！！！！！！！！！！");
    }


    @GetMapping("10")
    public void test0() throws InterruptedException {
        int containerCount = 1_0000;
        int storeCount = 20000;
        int materialCount = 4000000;
        ExecutorService executorServer = ExecutorUtil.getExecutorUtil().getExecutorServer();

        try {
            // 生成载具数据
            List<ContainerDao> containers = generateContainers(containerCount);
            containerService.saveBatch(containers);
            // 生成储位数据
            List<StoreLocalDao> stores = generateStores(storeCount, containers);
            storeLocalService.saveBatch(stores);
            System.out.println("=================生成储位数据====================");
            // 生成物料数据
//            List<MaterialDao> materials = generateMaterials(materialCount, containers, stores);
            for (int i = 0; i < 25; i++) {
                int finalI = i;
                executorServer.submit(() -> {
                    try {
                        int start = finalI * 10000 + 1;
                        int end = (finalI + 1) * 10000;
                        // 生成物料数据
                        System.out.println("=================生成物料数据====================");
                        List<MaterialDao> materials = generateMaterials(start, end, containers, stores);
                        System.out.println("=================完成生成物料数据: " + finalI + "====================");
                        materialService.saveBatch(materials);
                    } catch (Exception e) {
                        System.out.println("****************1: " + e.getMessage());
                    }
                });

            }
            System.out.println("数据生成完成！");
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (!executorServer.awaitTermination(1, TimeUnit.MINUTES)) {
            // 如果超过了60分钟还没有全部完成则强制中断剩余未完成的任务.
            System.out.println("线程任务超时》》》》》》》》》》》》");
        }


    }

    @GetMapping("11")
    public void test01() {
        Random random = new Random();
        List<StoreLocalDao> list = storeLocalService.list();
        List<StoreOutsideDao> arrayList = new ArrayList<>();
        int count = 0;
        String[] goodType = {"5", "3"};
        String[] wareType = {"1", "2"};
        String[] floor = {"M1", "M2"};
        String[] storeType = {"托盘储位", "料箱储位"};
        for (StoreLocalDao storeLocalDao : list) {
            if (count > 200) {
                break;
            }
            StoreOutsideDao storeOutsideDao = new StoreOutsideDao();
            BeanUtil.copyProperties(storeLocalDao, storeOutsideDao, CopyOptions.create().setIgnoreNullValue(true));
            storeOutsideDao.setGoodType(goodType[random.nextInt(2)]);
            storeOutsideDao.setStoreType(wareType[random.nextInt(2)]);
            int i = random.nextInt(2);
            storeOutsideDao.setFloor(floor[i]);
            storeOutsideDao.setStoreType(storeType[i]);
            arrayList.add(storeOutsideDao);
            count++;
        }
        storeOutsideService.saveBatch(arrayList);
    }

    @GetMapping("12")
    public void test02() {
        HashMap<String, List<StoreOutsideDao>> hashMap = new HashMap<>();
        List<StoreOutsideDao> list = storeOutsideService.list();
        String workIp = String.valueOf(SnowIdUtil.nextId());
        int count = 0;
        for (StoreOutsideDao storeOutsideDao : list) {
            int index = count >= 21 ? 8 : 3;
            if (count < 29) {
                if (hashMap.containsKey(workIp) && hashMap.get(workIp).size() < index) {
                    hashMap.get(workIp).add(storeOutsideDao);
                } else {
                    workIp = String.valueOf(SnowIdUtil.nextId());
                    List<StoreOutsideDao> storeOutsideList = new ArrayList<>();
                    storeOutsideList.add(storeOutsideDao);
                    hashMap.put(workIp, storeOutsideList);
                }
            }
            count++;
        }

        List<DispositionDao> dispositionList = new ArrayList<>();
        List<StoreOutsideDao> storeOutsideList = new ArrayList<>();
        String[] strType = {"1", "2", "3"};
        int countIndex = 0;
        for (Map.Entry<String, List<StoreOutsideDao>> entry : hashMap.entrySet()) {
            List<StoreOutsideDao> outsideList = entry.getValue();
            if (outsideList.size() == 8) {
                for (StoreOutsideDao storeOutsideDao : outsideList) {
                    storeOutsideDao.setGoodType("1");
                    storeOutsideDao.setFloor("M2");
                    storeOutsideDao.setStoreType("料箱储位");
                    storeOutsideService.update(storeOutsideDao);
                }
            }

            if (outsideList.size() == 3 && countIndex < 5) {

                for (int i = 0; i < outsideList.size(); i++) {
                    StoreOutsideDao storeOutsideDao = outsideList.get(i);
                    storeOutsideDao.setGoodType("0");
                    storeOutsideDao.setFloor("M1");
                    storeOutsideDao.setStoreType("托盘储位");
                    DispositionDao dispositionDao = new DispositionDao()
                            .setId(SnowIdUtil.nextId())
                            .setIp(entry.getKey())
                            .setFloor("M1")
                            .setLocation(storeOutsideDao.getId())
                            .setName(strType[i])
                            .setStatus(0)
                            .setIsSorting(1);
                    storeOutsideService.update(storeOutsideDao);
                    dispositionList.add(dispositionDao);
                }
            } else if (outsideList.size() == 3) {
                for (int i = 0; i < outsideList.size(); i++) {
                    StoreOutsideDao storeOutsideDao = outsideList.get(i);
                    storeOutsideDao.setGoodType("0");
                    storeOutsideDao.setFloor("M2");
                    storeOutsideDao.setStoreType("料箱储位");
                    DispositionDao dispositionDao = new DispositionDao()
                            .setId(SnowIdUtil.nextId())
                            .setIp(entry.getKey())
                            .setFloor("M2")
                            .setLocation(storeOutsideDao.getId())
                            .setName(strType[i])
                            .setStatus(0)
                            .setIsSorting(1);
                    storeOutsideService.update(storeOutsideDao);

                    dispositionList.add(dispositionDao);
                }
            }
            countIndex++;
            System.out.println(entry.getKey() + "   " + entry.getValue().size());
        }
        dispositionService.saveBatch(dispositionList);


    }

    @GetMapping("13")
    public void test03() throws InterruptedException {
        ExecutorService executorServer = ExecutorUtil.getExecutorUtil().getExecutorServer();
        final LambdaQueryWrapper<MaterialDao> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(MaterialDao::getItemBarCode);
        Set<String> hashSet = new HashSet<>();
        for (int i = 1; i < 25; i++) {
            int finalI = i;
            executorServer.submit(() -> {
                Page<MaterialDao> materialDaoList = materialMapper.selectPage(new Page<>(finalI, 100000), wrapper);
                List<MesSyncDao> mesSyncList = new ArrayList<>();
                System.out.println("*********第" + finalI + "页**************: " + materialDaoList.getRecords().size());
                for (MaterialDao materialDao : materialDaoList.getRecords()) {
                    if (!hashSet.contains(materialDao.getMaterialCode())) {
                        hashSet.add(materialDao.getMaterialCode());
                        LocalDateTime entryDate = randomDate(2020, 2025);
                        DateTimeFormatter yyMMdd = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                        String batchDatePart = entryDate.format(yyMMdd);
                        MesSyncDao mesSyncDao = new MesSyncDao()
                                .setId(String.valueOf(SnowIdUtil.nextId()))
                                .setMaterialCode(materialDao.getMaterialCode())
                                .setMaterialName(materialDao.getMaterialName())
                                .setMaterialTypeName(materialDao.getMaterialCategory())
                                .setDormancyPeriod(90)
                                .setMaterialSpecs(materialDao.getMeasurementMethod())
                                .setMaterialUnit(materialDao.getUnit())
                                .setSupplierCustomer(materialDao.getSupplierCustomer())
                                .setUpdateTime(batchDatePart)
                                .setOverissueLimit(100)
                                .setStandardWeight(100)
                                .setExpiryPeriod(90);
                        mesSyncList.add(mesSyncDao);
                    }
                }
                mesSyncService.saveBatch(mesSyncList);
                System.out.println("*********第" + finalI + "页**************: ");
            });
        }
        if (!executorServer.awaitTermination(1, TimeUnit.MINUTES)) {
            // 如果超过了60分钟还没有全部完成则强制中断剩余未完成的任务.
            System.out.println("线程任务超时》》》》》》》》》》》》");
        }
    }

    @GetMapping("14")
    public void test04() throws InterruptedException {
        ExecutorService executorServer = ExecutorUtil.getExecutorUtil().getExecutorServer();

        LambdaQueryWrapper<MaterialDao> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(MaterialDao::getContainerCode)
                .groupBy(MaterialDao::getContainerCode);

        List<MaterialDao> list = materialService.list(wrapper);
        for (MaterialDao materialDao : list) {
            executorServer.execute(() -> {
                String containerCode = materialDao.getContainerCode();
                MaterialDao material = materialService.findItemBarCodeByContainerCode(containerCode);
                Double materialWeight = materialService.countTotalMaterialWeight(containerCode);
                if (material != null) {
                    ContainerDao containerById = containerService.findDataOne(containerCode);
                    if (containerById != null) {
                        containerById.setItemBarCode(material.getItemBarCode());
                        containerById.setWeight(materialWeight);
                        containerService.update(containerById);
                    }
                }
            });
        }

        if (!executorServer.awaitTermination(1, TimeUnit.MINUTES)) {
            // 如果超过了60分钟还没有全部完成则强制中断剩余未完成的任务.
            System.out.println("线程任务超时》》》》》》》》》》》》");
        }
    }


    public StoreTotalMapper getStoreTotalMapper() {
        return storeTotalMapper;
    }
}
